package com.xhwl.logistics.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhwl.common.enums.vehicle.PayTypeEnum;
import com.xhwl.common.enums.vehicle.RechargeTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.vehicle.VehcPayConfig;
import com.xhwl.common.query.cent.vehicle.OrderQuery;
import com.xhwl.common.vo.cent.vehicle.CarPayVo;
import com.xhwl.common.vo.cent.vehicle.UnifiedOrderVO;
import com.xhwl.logistics.constant.WeChatPayConstants;
import com.xhwl.logistics.dao.VehcPayConfigDao;
import com.xhwl.logistics.service.IWeChatPayService;
import com.xhwl.logistics.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

import java.net.InetAddress;
import java.net.UnknownHostException;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @description:
 * @author: lu.Aaron
 * @create: 2021-08-12 09:22
 **/
//@Service
@Slf4j
public class WeChatPayServiceImpl implements IWeChatPayService {
    @Autowired
    private VehcPayConfigDao vehcPayConfigDao;
    @Override
    public ResultJson unifiedOrder(CarPayVo carPayVo, Account account, Short industryId) {
        Integer projectId = carPayVo.getProjectId();
        RechargeTypeEnum rechargeTypeEnum = carPayVo.getRechargeType();
        @NotNull Integer amount = carPayVo.getAmount();
        String orderNo = carPayVo.getOrderNo();
        @NotEmpty String plateNumber = carPayVo.getPlateNumber();
        Integer monthNum = carPayVo.getMonthNum();
        Date validBeginTime = carPayVo.getValidBeginTime();
        Date validEndTime = carPayVo.getValidEndTime();
        Integer carId = carPayVo.getCarId();
        Integer payerAccountId = account.getId();
        log.info("微信统一下单开始，项目：{},收费类型：{}",projectId,rechargeTypeEnum);
        //查询对接微信支付需要的商户相关信息
        VehcPayConfig vehcPayConfig = vehcPayConfigDao.selectOne(new QueryWrapper<VehcPayConfig>().eq("project_id", projectId).eq("type", PayTypeEnum.WECHAT.getKey()));
        //1.根据app统一下单开发者文档设置请求参数
        Map<String,String> param=new HashMap<>();
        //应用ID
        param.put("appid",vehcPayConfig.getAppId());
        //商户号
        param.put("mch_id",vehcPayConfig.getPartnerId());
        //随机字符串
        param.put("nonce_str", WeChatPayUtil.generateNonceStr());
        param.put("body","车场收费");
        String out_trade_no=null;
        //商户订单号 根据当前系统时间加随机序列来生成订单号
        if (!RechargeTypeEnum.TEMP_PARK_RECHARGE.equals(rechargeTypeEnum)) {
            //非临停缴费需系统自动生成账单号
            out_trade_no= NumberGenerator.number(15);
        }else{
            //临停缴费直接取orderNo
            out_trade_no= orderNo;
        }
        param.put("out_trade_no", out_trade_no);
        //标价金额
        param.put("total_fee", String.valueOf(amount));
        //终端IP
        param.put("spbill_create_ip",getHostIp());
        //交易类型
        param.put("trade_type","APP");
        param.put("notify_url",vehcPayConfig.getNotifyUrl());
        Map<String,Object> attach=new HashMap<>();
        //追加一个附加参数
        attach.put("rct",rechargeTypeEnum.getKey());
        attach.put("pn",plateNumber);
        attach.put("pId",projectId);
        attach.put("idId",industryId);
        attach.put("paId",payerAccountId);
        attach.put("pr",account.getName());
        if (null!=monthNum) {
            attach.put("mn",monthNum);
        }
/*        if (null!=validBeginTime) {
            attach.put("vbt",DateFormatUtil.date2Str(validBeginTime,"yyyy-MM-dd HH:mm:ss"));
        }*/
        if (null!=validEndTime) {
            attach.put("vet",DateFormatUtil.date2Str(validEndTime,"yyyy-MM-dd HH:mm:ss"));
        }
        if (null!=carId) {
            attach.put("cid",carId);
        }
        param.put("attach", JSON.toJSONString(attach));

        //2.将参数转成xml字符，并会自动携带签名
        String paramXml = null;
        Map<String, String> stringStringMap=null;
        try {
            paramXml = WeChatPayUtil.generateSignedXml(param, vehcPayConfig.getPartnerKey());
            //3.发送请求获取响应数据
            HttpUtils httpClient = new HttpUtils(WeChatPayConstants.UNIFIEDORDER_URL);
            httpClient.setHttps(true);
            httpClient.setXmlParam(paramXml);
            httpClient.post();
            //4.获取响应数据
            String content = httpClient.getContent();
            //4.1XML字符串转换为MAP
            stringStringMap  = WeChatPayUtil.xmlToMap(content);
        } catch (Exception e) {
            log.error("将参数转成xml字符，并会自动携带签名失败");
        }
        //4.2生成二次签名给前端调起微信支付
        String secondTimestamp = DateFormatUtil.getSecondTimestamp(new Date());
        Map<String,String> generateSignMap=new HashMap<>();
        generateSignMap.put("appid",vehcPayConfig.getAppId());
        generateSignMap.put("partnerid",vehcPayConfig.getPartnerId());
        generateSignMap.put("noncestr",WeChatPayUtil.generateNonceStr());
        generateSignMap.put("prepayid",stringStringMap.get("prepay_id"));
        generateSignMap.put("package", "Sign=WXPay");
        generateSignMap.put("timestamp",secondTimestamp);
        String sign = null;
        try {
            sign = WeChatPayUtil.generateSignature(generateSignMap, vehcPayConfig.getPartnerKey());
            log.info("微信统一下单成功，项目：{},收费类型：{}",projectId,rechargeTypeEnum);
        } catch (Exception e) {
            log.error("微信统一下单失败，项目：{},收费类型：{}",projectId,rechargeTypeEnum);
        }
        //5.将stringStringMap转成前端页面所需要数据的unifiedOrderVO
        UnifiedOrderVO unifiedOrderVO = new UnifiedOrderVO(vehcPayConfig.getAppId(),vehcPayConfig.getPartnerId(),stringStringMap.get("prepay_id"),"Sign=WXPay",param.get("nonce_str"), secondTimestamp,sign,carPayVo.getAmount(),out_trade_no);
        return ResultJson.success(unifiedOrderVO);
    }

    @Override
    public ResultJson orderQuery(OrderQuery orderQuery) {
        @NotEmpty String outTradeNo = orderQuery.getOutTradeNo();
        @NotNull Integer projectId = orderQuery.getProjectId();
        //查询对接微信支付需要的商户相关信息
        VehcPayConfig vehcPayConfig = vehcPayConfigDao.selectOne(new QueryWrapper<VehcPayConfig>().eq("project_id", projectId));
        //1.根据查询订单扫码开发者文档设置请求参数
        Map<String,String> param=new HashMap<>();
        param.put("appid",vehcPayConfig.getAppId());
        param.put("mch_id",vehcPayConfig.getPartnerId());
        param.put("nonce_str", WeChatPayUtil.generateNonceStr());
        param.put("out_trade_no",outTradeNo);
        //2.将参数转成xml字符，并会自动携带签名
        Map<String, String> resultMap = null;
        try {
            String paramXml = WeChatPayUtil.generateSignedXml(param, vehcPayConfig.getPartnerKey());
            //3.发送请求
            HttpUtils httpClient = new HttpUtils(WeChatPayConstants.ORDERQUERY_URL);
            httpClient.setHttps(true);
            httpClient.setXmlParam(paramXml);
            httpClient.post();
            //获取响应数据
            String content = httpClient.getContent();
            resultMap = WeChatPayUtil.xmlToMap(content);
        } catch (Exception e) {
            log.error("微信查询支付订单状态失败");
        }
        return ResultJson.success(resultMap);
    }

    /**
     * 得到本地机器的IP
     * @return
     */
    private static String getHostIp(){
        String ip = "";
        try{
            ip = InetAddress.getLocalHost().getHostAddress();
        }catch(UnknownHostException e){
            e.printStackTrace();
        }
        return ip;
    }
}

